import configTool from '../../../com/configTool';
import initDB from '../Util/initDB';
import axios from 'axios';
import crypto from 'crypto';
import readFromDB from '../Util/readFromDB';
import saveToDB from '../Util/saveToDB';
import DBConnectTool from '../../../com/DBTool/DBConnectTool';
import sleep from '../../sleep';


let Loading = true;
const DBName = 'tile.googleapis.com';
const Cesium = require('../../../../ext/Cesium-1.130/index.js');
const defaultAccessToken = Cesium.Ion.defaultAccessToken;


type ResponseType = | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream';

let key = '';
let session = '';

async function getWallData(url: string, responseType: ResponseType = 'json'): Promise<any> {
    return new Promise((resolve, reject) => {
        axios
            .get(url, {
                responseType: responseType,
                timeout: 1000,
                proxy: {
                    protocol: 'http',
                    host: '127.0.0.1',
                    port: 7890
                }
            })
            .then(e => resolve(e.data))
            .catch(e => {
                console.log(e);
                resolve(null);
            });
    });
}

let Google3DTiles = {
    isRunning: false,
    async getRootJson(needGetToken = true) {
        while (this.isRunning) {
            await sleep(100);
        }

        console.log('Google3DTiles 初始化中...');

        await configTool.init();
        configTool.preservableONDB() && await initDB(DBName);

        await initDB(DBName);
        await DBConnectTool.openDB(DBName);
        let tileSetRoot = null;

        if (needGetToken) {
            const endpointUrl = 'https://api.cesium.com/v1/assets/2275207/endpoint?access_token=' + defaultAccessToken;
            try {
                const authority = await fetch(endpointUrl).then(e => e.json());
                const rootUrl = authority.options.url;

                // 模型数据的外层 Root JSON，不包含实际数据，仅包含鉴权信息
                const rootJson = await getWallData(rootUrl, 'json');
                const tileSetRootRelativeUri = rootJson.root.children[0].children[0].content.uri;

                key = new URL(rootUrl).searchParams.get('key') || '';
                session = new URL('https://tile.googleapis.com' + tileSetRootRelativeUri).searchParams.get('session') || '';

                tileSetRoot = rootJson;
            } catch (e) {
                console.log(endpointUrl);
                console.warn('获取资源令牌失败');
            }
        }
        if (!tileSetRoot) {
            const tileSetRootRelativeUri = '/v1/3dtiles/datasets/CgA/files/UlRPVEYuYnVsa21ldGFkYXRhLnBsYW5ldG9pZD1lYXJ0aCxidWxrX21ldGFkYXRhX2Vwb2NoPTk4MixwYXRoPSxjYWNoZV92ZXJzaW9uPTYsYWxpZ25tZW50X3ZlcnNpb249Uk9DS1RSRUVfOTgyX0dPT0dMRV9EQVRVTV8yMDI0MDUwOFQwNzUzWl9nZW5lcmF0ZWRfYXRfMjAyNDA3MTJUMTIwN1o.json';
            const {json} = await this.getJson(tileSetRootRelativeUri, true);
            tileSetRoot = json;
        }


        return {tileSetRoot};
    },
    async hasFile(uri: string) {
        const dbPath = uri.replaceAll('/', '\\');
        const dbTool = await DBConnectTool.openDB(DBName);
        const file = await dbTool.getFileByFullPath(dbPath);
        return !!file;
    },
    async getJson(uri: string, needSaveToDB = true) {
        const {err, buffer, dataSource} = await this.getBuffer(uri, needSaveToDB, true);
        if (buffer) {
            return {err, json: JSON.parse(buffer.toString()), dataSource};
        } else {
            return {err, json: null, dataSource};
        }
    },
    async getBuffer(uri: string, needSaveToDB = true, needCompress = false) {
        const dbPath = uri.replaceAll('/', '\\');
        let [err, buffer, dataSource] = await readFromDB({DBName: DBName, relativePath: dbPath});

        if (buffer === null && key && session) {
            buffer = await getWallData(`https://tile.googleapis.com${uri}?session=${session}&key=${key}`, 'arraybuffer');

            if (buffer) {
                dataSource = 'Net';
                err = null;
            } else {
                err = '获取 tile.googleapis.com 文件失败';
            }
            if (needSaveToDB) {
                // 存入缓存文件
                const md5Str = crypto.createHash('md5').update(buffer).digest('hex');
                if (md5Str) {
                    saveToDB({DBName: DBName, relativePath: dbPath, buffer}, needCompress).then();
                }
            }
        } else if (key === '' || session === '') {
            err = '请先配置 key 和 session';
        }

        err && console.log(err);

        return {err, buffer, dataSource};
    }
};

export default Google3DTiles;
